package redis

import (
	"fmt"
	"github.com/go-redis/redis"
	"smart-sensor-cloud/internal/config"
	"time"
)

type (
	Client interface {
		Ping() *redis.StatusCmd
		Get(key string) *redis.StringCmd
		Set(key string, value interface{}, expire time.Duration) *redis.StatusCmd
		Expire(key string, expire time.Duration) *redis.BoolCmd
		Exists(keys ...string) *redis.IntCmd
		TxPipeline() redis.Pipeliner
		Del(keys ...string) *redis.IntCmd
		Close() error
	}

	Manager struct {
		cli       Client
		keyPrefix string
	}
)

func NewManager(conf *config.RedisConfig) *Manager {
	cli := redis.NewClient(&redis.Options{
		Addr:     fmt.Sprintf("%s:%d", conf.Host, conf.Port),
		Password: conf.Password,
		DB:       conf.DefaultDB,
	})
	return &Manager{
		cli:       cli,
		keyPrefix: conf.KeyPrefix,
	}
}

func (man *Manager) keyWrapper(key string) string {
	return fmt.Sprintf("%s-%s", man.keyPrefix, key)
}

func (man *Manager) Ping() error {
	cmd := man.cli.Ping()
	return cmd.Err()
}

func (man *Manager) Set(key string, value interface{}, expire time.Duration) error {
	cmd := man.cli.Set(man.keyWrapper(key), value, expire)
	return cmd.Err()
}

func (man *Manager) Delete(key string) (bool, error) {
	cmd := man.cli.Del(man.keyWrapper(key))
	if err := cmd.Err(); err != nil {
		return false, err
	}

	return cmd.Val() > 0, nil
}

func (man *Manager) Exist(key string) (bool, error) {
	cmd := man.cli.Exists(man.keyWrapper(key))
	if err := cmd.Err(); err != nil {
		return false, err
	}

	return cmd.Val() > 0, nil
}

func (man *Manager) Close() error {
	return man.cli.Close()
}
